package com.zmn.plat.business.impl.servcategory;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import com.zmn.common.utils.string.StringUtil;
import com.zmn.plat.common.util.SimpleSpellUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.constant.StatusConsts;
import com.zmn.common.dictionary.GlobalDict;
import com.zmn.common.dto.StatusDTO;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.string.InitialUtil;
import com.zmn.plat.business.interfaces.category.BaseCategoryBService;
import com.zmn.plat.business.interfaces.servcategory.ServCategoryBService;
import com.zmn.plat.common.constant.ProductConsts;
import com.zmn.plat.common.exception.PlatException;
import com.zmn.plat.model.entity.category.BaseCategory;
import com.zmn.plat.model.entity.extension.serv.category.ExtensionServCategory;
import com.zmn.plat.model.entity.product.ServProduct;
import com.zmn.plat.model.entity.product.ServProductQuery;
import com.zmn.plat.model.entity.servcategory.ServCategory;
import com.zmn.plat.services.interfaces.category.BaseCategoryService;
import com.zmn.plat.services.interfaces.extension.serv.category.ExtensionServCategoryService;
import com.zmn.plat.services.interfaces.product.ServProductService;
import com.zmn.plat.services.interfaces.servcategory.ServAssCategoryService;
import com.zmn.plat.services.interfaces.servcategory.ServCategoryService;

/**
 * 描述: 服务类型业务实现类接口
 *
 * @author wangjie
 * @since 16:40 2019/5/20
 **/
@Service
public class ServCategoryBServiceImpl implements ServCategoryBService {

    private Logger logger = LoggerFactory.getLogger(ServCategoryBServiceImpl.class);

    private ServCategoryService servCategoryService;

    private ExtensionServCategoryService extensionServCategoryService;

    private BaseCategoryService baseCategoryService;

    private BaseCategoryBService baseCategoryBService;

    private ServProductService servProductService;

    private ServAssCategoryService servAssCategoryService;

    @Autowired
    public ServCategoryBServiceImpl(ServCategoryService servCategoryService, ServAssCategoryService servAssCategoryService, BaseCategoryService baseCategoryService,
        BaseCategoryBService baseCategoryBService, ServProductService servProductService, ExtensionServCategoryService extensionServCategoryService) {
        this.servCategoryService = servCategoryService;
        this.servAssCategoryService = servAssCategoryService;
        this.baseCategoryService = baseCategoryService;
        this.baseCategoryBService = baseCategoryBService;
        this.servProductService = servProductService;
        this.extensionServCategoryService = extensionServCategoryService;
    }

    /**
     * 提供精确的乘法运算
     */
    protected double mul(String dou1, String dou2) {
        BigDecimal big1 = new BigDecimal(dou1);
        BigDecimal big2 = new BigDecimal(dou2);
        return big1.multiply(big2).doubleValue();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateShowStatusByServCategId(List<Integer> arrayIds, int status, String mcStaffName) {
        servCategoryService.updateShowStatusBatch(arrayIds, status, mcStaffName);
        for (Integer servCategId : arrayIds) {
            List<BaseCategory> categoryOneList = servAssCategoryService.findCategoryOneByServIdAndShowType(servCategId, ProductConsts.EC_PRODUCT_TYPE);
            List<Integer> categoryOneIds = categoryOneList.stream().map(BaseCategory::getCategId).collect(Collectors.toList());
            if (categoryOneIds.size() != 0) {
                baseCategoryService.updateStatusBatch(arrayIds, status, mcStaffName);
            }
            List<BaseCategory> assCategoryTwoList = servAssCategoryService.findCategoryTwoByServIdAndShowType(servCategId, ProductConsts.EC_PRODUCT_TYPE);
            List<Integer> assCategoryTwoIds = assCategoryTwoList.stream().map(BaseCategory::getCategId).collect(Collectors.toList());
            if (assCategoryTwoIds.size() != 0) {
                baseCategoryService.updateStatusBatch(assCategoryTwoIds, status, mcStaffName);

                // 根据二级分类id查询启用的前台产品
                ServProductQuery servProductQuery = new ServProductQuery();
                servProductQuery.setStatus(GlobalDict.STATUS_ENABLE);
                servProductQuery.setShowType(ProductConsts.EC_PRODUCT_TYPE);
                servProductQuery.setCategIds(assCategoryTwoIds);
                servProductQuery.setServCategId(servCategId);
                List<ServProduct> servProductList = servProductService.listByQuery(servProductQuery);
                List<Integer> serProductIds = servProductList.stream().map(ServProduct::getProductId).collect(Collectors.toList());
                if (serProductIds.size() != 0) {
                    StatusDTO dto = new StatusDTO();
                    dto.setIds(serProductIds);
                    dto.setStatus(status);
                    dto.setUpdater(mcStaffName);
                    servProductService.updateStatusBatch(dto);
                }
            }
        }
    }

    @Override
    public Integer updateFrontByKey(ServCategory category, String operator) {
        checkTariffName(category.getTariffName(), category.getCategId());
        ServCategory result = servCategoryService.findByKey(category.getCategId());
        Integer showSort = category.getShowSort() == null ? 1 : category.getShowSort();
        result.setShowSort(showSort);
        String showFirstLetter = "";
        String showSimpleSpell = "";
        if (StringUtil.isBlank(category.getShowSimpleSpell())) {
            showFirstLetter = InitialUtil.getFristEnName(category.getShowName());
            showSimpleSpell = SimpleSpellUtil.parseNameToSimpleSpell(category.getShowName(),null);
        } else {
            showSimpleSpell = category.getShowSimpleSpell().toUpperCase();
            showFirstLetter = category.getShowSimpleSpell().substring(0,1);
        }
        result.setShowFirstLetter(showFirstLetter);
        result.setShowSimpleSpell(showSimpleSpell);
        result.setShowName(category.getShowName());
        result.setShowUpdater(operator);
        result.setShowUpdateTime(DateUtil.getNow());
        result.setShowCategoryPagePicture(category.getShowCategoryPagePicture());
        result.setShowHomePageIcon(category.getShowHomePageIcon());
        result.setTariffName(category.getTariffName());
        result.setTariffStatus(category.getTariffStatus());
        Integer updateResult = servCategoryService.updateFrontByKey(result);
        // 级联禁用计价器：前台产品分类，前台产品计价器状态都禁用
        // if(category.getTariffStatus().equals(GlobalConsts.NO)){
        // disableTariff(category.getCategId(),operator);
        // }
        return updateResult;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addEdit(ServCategory category, String operator) {
        Date now = DateUtil.getNow();
        Integer categId = category.getCategId();

        if (!NumberUtil.isPositiveInteger(category.getSort())) {
            category.setSort(GlobalConsts.TOP_ID);
        }

        try {
            if (categId == null) {
                String firstLetter = InitialUtil.getFristEnName(category.getName());
                String simpleSpell = SimpleSpellUtil.parseNameToSimpleSpell(category.getName(),null);
                category.setCreater(operator);
                category.setShowCreater(operator);
                category.setCreateTime(now);
                category.setShowCreateTime(now);
                category.setUpdater(operator);
                category.setShowUpdater(operator);
                category.setShowUpdateTime(now);
                category.setUpdateTime(now);
                category.setStatus(GlobalConsts.YES);
                category.setShowStatus(GlobalConsts.YES);
                category.setSort(1);
                category.setShowSort(1);
                category.setShowName(category.getName());
                category.setShowFirstLetter(firstLetter);
                category.setFirstLetter(firstLetter);
                category.setSimpleSpell(simpleSpell);
                category.setShowSimpleSpell(simpleSpell);
                servCategoryService.insert(category);
                categId = servCategoryService.findByName(category.getName()).getCategId();
                // 新增后台服务分类时同步数据到推广服务分类表中
                ExtensionServCategory extensionServCategory = new ExtensionServCategory();
                extensionServCategory.setCategId(categId);
                extensionServCategory.setName(category.getName());
                extensionServCategory.setStatus(GlobalConsts.NO);
                extensionServCategory.setSort(1);
                extensionServCategory.setFirstLetter(firstLetter);
                extensionServCategory.setCreater(operator);
                extensionServCategory.setCreateTime(now);
                extensionServCategory.setUpdater(operator);
                extensionServCategory.setUpdateTime(now);
                extensionServCategoryService.insert(extensionServCategory);
            } else {
                category.setUpdater(operator);
                category.setUpdateTime(now);
                servCategoryService.updateNameKey(categId, category.getName(), operator);
            }

        } catch (org.springframework.dao.DuplicateKeyException ex) {
            logger.error("服务类型【{}】已经存在，不能重复添加！", category.getName());
            throw new PlatException(StatusConsts.STATUS_ERROR, "服务类型已经存在，不能重复添加！");
        } catch (Exception ex) {
            logger.error("[zmn]新增/修改产品分类失败,category:{},ex:{}", category, ex.getMessage(), ex);
            throw new PlatException(StatusConsts.STATUS_ERROR, "操作失败！");
        }
    }

    private void checkTariffName(String tariffName, Integer categId) {
        ServCategory query = new ServCategory();
        query.setTariffName(tariffName);
        List<ServCategory> list = servCategoryService.listByQuery(query);
        if (!CollectionUtils.isEmpty(list)) {
            if (list.size() > 1) {
                throw new PlatException("同一级的计价器名称不可相同");
            }
            ServCategory category = list.get(0);
            if (!category.getCategId().equals(categId)) {
                throw new PlatException("同一级的计价器名称不可相同");
            }
        }
    }
}
